﻿#define _CRT_SECURE_NO_WARNINGS
#pragma execution_character_set("utf-8")

#include <stdio.h> 

#include <string.h>

#include <stdlib.h>

#include "struct.h" 

#include "enclosure.h"


int Cmp(const void* p1, const void* p2) {  //这是给qsort写的比较函数 //还不清楚方向对不对//

    struct comp* tmp1 = (comp*)p1;

    struct comp* tmp2 = (comp*)p2;

    if ((int)(tmp1->complex_grade < tmp2->complex_grade)) return 1;

    if ((int)(tmp1->complex_grade > tmp2->complex_grade)) return -1;

    if ((int)(tmp1->complex_grade == tmp2->complex_grade)) return 0;

}

float Get_gpa(float grade) { // 成绩转绩点

    if (grade < 0) return -1; 

    if (grade < 60) return 0;

    if (grade < 64) return 1.0;

    if (grade < 67) return 1.3;

    if (grade < 70) return 1.7;

    if (grade < 74) return 2.0;

    if (grade < 77) return 2.3;

    if (grade < 80) return 2.7;

    if (grade < 84) return 3.0;

    if (grade < 87) return 3.3;

    if (grade < 90) return 3.7;

    return 4.0;

}

float Calu_common(student* p_cur, rule* diy) { // 计算学生的基本成绩

    read_subject(p_cur);

    subject* tmp = (p_cur->pH_subject)->next;

    float point = 0, gpa = 0;

    while (tmp != NULL) {

        //printf("%s %s %d\n", p_cur->name,tmp->name, tmp->type);

        if (diy->type[tmp->type] != -1) { // 筛选学科类别

            tmp = tmp->next;

            continue;  // 当这们课不在选择范围，就直接跳过

        }

        if (diy->judge == -1) { //不使用自定义列表

            point += tmp->cavlue; // 记录学分

            gpa += (tmp->gpa*tmp->cavlue); // 记录绩点

        }

        else {

            for (int i = 0; i < diy->judge; i++) { // 筛选自定义列表

                if (strcmp(diy->filter[i], tmp->node) == 0) { // 如果当前学科在自定义列表里面

                    point += tmp->cavlue; // 记录学分

                    gpa += (tmp->gpa * tmp->cavlue); // 记录绩点

                    break; // 筛选结束

                }

            }

        }

        tmp = tmp->next;

    }

    if (point <= 0) return -1; // 这个学生的所有学科都不在筛选范围内

    return (gpa / point);

}

float Calu_bouns(student* p_cur) {  // 计算学生综合成绩的函数

    float contest = 0, other = 0; // 竞赛和其他（项目和论文不能重复加分）两类

    read_medal(p_cur);

    medal* p_medal = (p_cur->pH_medal)->next;

    while (p_medal != NULL) { // 遍历每个竞赛成绩，找出其中最大的(同类加分不叠加)

        float temp = p_medal->level;

        if (temp > contest) {

            contest = temp;

        }

        p_medal = p_medal->next;

    }

    write_medal(p_cur);

    read_project(p_cur);

    project* p_project = (p_cur->pH_project)->next;

    while (p_project != NULL) { // 遍历每个项目成绩，找出其中最大的

        if (strcmp(p_project->member[0], p_cur->name)) { //是不是第一责任人

            if (0.1 > other) { other = 0.1; }

        }

        else if (strcmp(p_project->member[1], p_cur->name)) { //是不是第二责任人

            if (0.05 > other) { other = 0.05; }

        }

        p_project = p_project->next;

    }

    write_project(p_cur);

    read_paper(p_cur);

    paper* p_paper = (p_cur->pH_paper)->next;

    while (p_paper != NULL) { // 遍历每个论文加分，找出其中最大的

        float temp = p_paper->level;

        if (temp > other) { other = temp; }

        p_paper = p_paper->next;

    }

    write_paper(p_cur);

    return (contest + other);

}

int Check_int(char* obj, int length, int ran1, int ran2) { // 检测无符号整型数据的合法性 并返回无符号整型数据（不合法时返回-1），为空时返回-2

    if (length == 0) return -2;

    int temp = 0, mult = 1;

    for (int i = length - 1; i >= 0; i--) {

        if ('0' > obj[i] || obj[i] > '9') return -1;  // 格式不符合整数

        temp += (((int)obj[i] - '0') * mult);

        mult *= 10;

    }

    if (strcmp(obj, "") == 0) return 0;

    if (temp<ran1 || temp>ran2) return -1; // 整数值的范围不符合要求

    return temp;

}

float Check_float(char* obj, int length, float ran1, float ran2) { // 检测无符号整型数据的合法性 并返回无符号整型数据（不合法时返回-1）,为空时返回-2

    if (length == 0) return -2;

    int dot = length; float temp = 0, mult1 = 1, mult2 = 0.1;

    for (int i = 0; i < length; i++) { if (obj[i] == '.') { dot = i; } }

    for (int i = dot - 1; i >= 0; i--) {

        if ('0' > obj[i] || obj[i] > '9') return -1; //格式不符合数字

        int tmp = obj[i] - '0';

        temp += ((float)tmp * mult1);

        mult1 *= 10;

    }

    for (int i = dot + 1; i < length; i++) {

        if ('0' > obj[i] || obj[i] > '9') return -1; //格式不符合数字

        int tmp = obj[i] - '0';

        temp += ((float)tmp * mult2);

        mult2 /= 10;

    }

    if (temp<ran1 || temp>ran2) return -1; // 浮点数值的范围不符合要求

    return temp;

}

int Check_split(char tmp[][30], char str[], char mark, int max, int unit) {

    //分割 tmp为存入空间 str为分割目标 a（一般是空格/点）为分隔符 max为分割个数上限(一般为20或3) unit为单位字数上限

    int i = 0, j = 0, k = 0; // i表示当前分割的数量， j是tmp的遍历指针 k是str

    while (str[k] != '\0') {

        if (str[k] != mark) { tmp[i][j] = str[k]; j++; } // 没有碰到分隔符时正常录入

        else if (j != 0) { tmp[i][j] = '\0'; i++; j = 0; } // 否则判断j当前指向的字符串是否为空，防止录入空的字符串

        if (i >= max) { return -1; }  // 成员个数超出上限

        if (j >= unit) { return -2; }// 单个成员长度超出上限

        k++;

    }

    if (j > 0) { tmp[i][j] = '\0';  return (i+1); } // 末尾无分割符 返回成员个数

    else { return i; } // 末尾有分割符

}


int Check_space(char* str) { // 是否含有空格

	char* p = str;

	while (*p != '\0') {

		if (*p == ' ') { return 1; }

		p++;

	}

	return 0;

}

student* id_search_student(char* id) {  // 返回当前学生的编号的指针

    student* p;

    p = pH_student;

    while (p != NULL && strcmp(p->id, id) != 0)   p = p->next;

    return p;  //若不存在则返回NULL

}

subject* node_search_subject(student* p, char* node) {  // 返回当前学生的编号为node的成绩的指针

    subject* q;

    q = p->pH_subject;

    while (q != NULL && strcmp(q->node, node) != 0) q = q->next;

    return q; //找不到的话返回NULL

}

project* node_search_project(student* p, char* node) { // 返回当前学生的编号为node的项目的指针

    project* q;

    q = p->pH_project;

    while (q != NULL && strcmp(q->node, node) != 0) q = q->next;

    return q; //若不存在则返回NULL

}

paper* node_search_paper(student* p, char* node) { // 返回当前学生的编号为node的论文的指针

    paper* q;

    q = p->pH_paper;

    while (q != NULL && strcmp(q->node, node) != 0) q = q->next;

    return q; //若不存在则返回NULL

}

medal* node_search_medal(student* p, char* node) {  // 返回当前学生的编号为node的论文的指针

    medal* q;

    q = p->pH_medal;

    while (q != NULL && strcmp(q->node, node) != 0) q = q->next;

    return q; //若不存在则返回NULL

}

void print_subject(subject* les) {

    printf("学科名称：%s\n学分:%.2f\n成绩: %.2f\ngpa: %.2f\n", (les->name), (les->cavlue), (les->grade), (les->gpa));

}

void print_project(project* pro) {

    printf("姓名: %s\n指导老师: %s\n项目编号: %8s\n成员:\n", pro->name, pro->teacher, pro->node);

    for (int i = 0; (i < 20) && (strcmp(pro->member[i], "") != 0); i++) {

        printf("%s\t", pro->member[i]);

        if ((i + 1) % 5 == 0) printf("\n");

    }

    printf("开始日期: %4d.%2d.%2d\n结束日期: %4d.%2d.%2d\n", pro->start.year, pro->start.month, pro->start.day, pro->finish.year, pro->finish.month, pro->finish.day);

    printf("项目加分: %.2f\n", pro->level);

}

void print_paper(paper* pap) {

    printf("论文名称: %s \n期刊号: %s \n加分情况: %.2f \n", pap->name, pap->node, pap->level);

    printf("发表日期: %4d.%2d.%2d\n", pap->date.year, pap->date.month, pap->date.day);

    for (int i = 0; (i < 20) && (strcmp(pap->member[i], "") != 0); i++) {

        printf("%s\t", pap->member[i]);

        if ((i + 1) % 5 == 0) printf("\n");

    }

    printf("论文加分: %.2f\n", pap->level);

}

void print_medal(medal* med) {

    printf("所获竞赛名称：%s\n主办方：%s\n", med->name, med->organizer);

    printf("成员名称：\n");

    for (int i = 0; (i < 20) && (strcmp(med->member[i], "") != 0); i++) {

        printf("%s\t", med->member[i]);

        if((i+1)%5==0) printf("\n");

    }

    printf("竞赛加分: %.2f\n", med->level);

}



